
import { Ref, ref, watchEffect, toValue, computed } from 'vue'
import Debug from 'debug'
const debug = Debug('tlf-usemedia')
export function usemedia(videoElement: Ref<HTMLMediaElement> | null) {
    const video = ref<HTMLMediaElement | null>(null)
    const stream = ref<MediaStream | null>(null)
    const allRes = ref([
        {
            title: '320x240',
            video: {
                video: { width: { exact: 480 }, height: { exact: 1080 / 4 } }
            }
        },

        {
            title: '640x480',
            video: {
                video: { width: { exact: 1920 / 2 }, height: { exact: 1080 / 2 } }
            }
        },
        {
            title: '1920x1080',
            video: {
                video: { width: { exact: 1920 }, height: { exact: 1080 } }
            }
        },
        {
            title: '1920x1080',
            video: {
                video: { width: { exact: 2560 }, height: { exact: 1440 } }
            }
        },

    ])
    // const currRes = ref(allRes.value[0].video.video)
    const currRes = ref(0)
    const width = computed(() => {
        return 1920 / 4
        return allRes.value[currRes.value].video.video.width.exact
    })
    const height = computed(() => {
        return 1080 / 4
        return allRes.value[currRes.value].video.video.height.exact
    })
    watchEffect(() => {
        video.value = toValue(videoElement)
    })
    /**
     * 
     * 从共享屏幕获取视频
     */
    async function shareScreen() {
        let options = { audio: true, video: true };
        let streamTmp = await navigator.mediaDevices.getDisplayMedia(options)
        // play(streamTmp)

        streamTmp.getVideoTracks()[0].addEventListener('ended', () => {

        });
        return streamTmp
    }
    /**
     * 从摄像头获取视频
     */

    /**
     * 获取媒体
     * @param type 获取媒体的类型
     * @param audioInputId 音频设备的id
     * @param videoInputId 视频设备的id
     */
    async function shareCamera(type: "all" | 'audio' | 'video' = 'all', options: MediaStreamConstraints = {}) {
        // 单独获取视频和音频 要不然又一个出问题都会导致另一个也没法用
        const stream = new MediaStream()
        let opt = Object.assign({
            audio: true,
            video: {
                width: { ideal: 640 },
                height: { ideal: 480 },
                // deviceId: videoInputId.value,
                frameRate: { ideal: 30 },
                facingMode: "user"
            }
        }, options || {})
        if (type === 'all' || type === 'audio') {
            try {

                const streamAudio = await navigator.mediaDevices.getUserMedia({ audio: opt.audio })
                stream.addTrack(streamAudio.getAudioTracks()[0])

            } catch (e) {
                return false
            }
        }

        if (type === 'all' || type === 'video') {
            try {

                const streamVideo = await navigator.mediaDevices.getUserMedia({ video: opt.video });
                stream.addTrack(streamVideo.getVideoTracks()[0])
            } catch (error) {
                return false
            }
        }
        return stream
    }
    /**     
     * 播放视频
     */
    async function play(tmpStream: MediaStream) {
        if (tmpStream) {
            stop()
            stream.value = tmpStream
        }
        if (video.value) {
            if (audioOutputId.value) {
                (video.value as any).setSinkId(audioOutputId.value)
            }
            if (stream.value) {
                video.value.srcObject = stream.value
                video.value.muted = true
            } else {
                return false
            }
        }
        return true
    }
    /** 
     * 停止播放视频
     */
    function stop() {
        if (video.value && stream.value) {
            const tracks = stream.value.getTracks()
            tracks.forEach(v => {
                v.stop()
            })
            stream.value = null
        }
    }

    const audioInputId = ref('')
    const audioOutputId = ref('')
    const videoInputId = ref('')

    const audioInputs = ref<MediaDeviceInfo[]>([])
    const audioOutputs = ref<MediaDeviceInfo[]>([])
    const videoInputs = ref<MediaDeviceInfo[]>([])

    async function getDevices(): Promise<MediaDeviceInfo[] | false> {
        try {
            let devices = await navigator.mediaDevices.enumerateDevices()
            audioInputs.value = []
            videoInputs.value = []
            audioOutputs.value = []
            devices.forEach(v => {
                if (v.kind == 'audioinput') {
                    audioInputs.value.push(v)
                }
                if (v.kind == 'videoinput') {
                    videoInputs.value.push(v)
                }
                if (v.kind == 'audiooutput') {
                    audioOutputs.value.push(v)
                }
            })

            audioInputId.value = audioInputs.value[0]?.deviceId
            audioOutputId.value = audioOutputs.value[0]?.deviceId
            videoInputId.value = videoInputs.value[0]?.deviceId
            return devices
        } catch (error) {
            debug('getDevices', error)
            return false
        }

    }

    return {
        getDevices,
        audioInputs,
        videoInputs,
        audioOutputs,
        audioInputId,
        audioOutputId,
        videoInputId,
        play,
        stop,
        shareCamera,
        shareScreen,
        allRes,
        width,
        height,
        stream
    }
}